use tokio::io::AsyncReadExt;

use crate::{error::AppErr, utils::new_bytes};


const HEAD0: u8 = 0xE1;
const HEAD1: u8 = 0x1E;


// 0,1 head
// 2 len
// 3 type
// 4 seq
// sum end
pub async fn read<R: AsyncReadExt + Unpin>(r: &mut R) -> Result<Box<[u8]>, AppErr> {

    let mut buf: [u8; 1] = [0; 1];
    let mut flag = false;

    loop {
        r.read(&mut buf).await?;
        if flag && (buf[0] == HEAD1) {
            break;
        }
        flag = buf[0] == HEAD0;
    }
    _ = r.read(&mut buf).await;
    let mut len = buf[0] as usize;
    if len < 7 {
        return AppErr::Proto("len < 7").to();
    }   

    len -= 3;
    let mut buf = new_bytes(len);
    r.read_exact(&mut buf).await?;

    let mut s = 0;
    for i in 0..(len - 2) {
        s = s ^ buf[i];
    }

    if s != buf[len - 2] {
        return AppErr::Proto("check sum invalid").to();
    }

    if s != buf[len - 1] {
        return AppErr::Proto("end invalid").to();
    }

    Ok(buf)
}

